
/*
	filename:		CCardStack.cpp
	author:			Rico Roberto Zu�iga
	last modified:	9/12/03

	description:	Card stack data structure subs.
*/
#include "CCardStack.h"
#include <vector>
#include <algorithm>

void CCardStack::NewDeck()
{
	int Id = 1;

	this->clear();
	this->resize(52);

    for(VI vi = this->begin(); vi != this->end(); ++vi, ++Id)
        vi->SetIdx(Id);
}

void CCardStack::Shuffle()
{
//	srand((unsigned)time(0));
	std::random_shuffle(this->begin(), this->end());
}

void CCardStack::Clear()
{
	this->clear();
}

void CCardStack::Reverse()
{
	std::reverse(this->begin(), this->end());
}

int CCardStack::Value() const {
  // Kristina wrote this, because she didn't know Andres already had
//  if (Size() != 3)
//    return 0;

  int score, suitScore[4] = {0};

  for (CONST_VI ci=begin(); ci!=end(); ci++) {
    if (!ci->IsJoker())
      suitScore[ci->Suit()] += ci->Value();
  }
  score = suitScore[0];
  for (int i=1; i<4; i++)
    if (suitScore[i] > score)
      score = suitScore[i];

  return score;

// Andres wrote this
//   int max = 0;
//     for (int suit = Spades; suit <= Diamonds; suit++) {
//         int suitTotal = 0;
//         for (VI vi = this->begin(); vi != this->end(); vi++) {
//             if (vi->Suit() == suit) {
//                 suitTotal += vi->Value();
//             }
//         }
//         if (suitTotal > max) {
//             max = suitTotal;
//         }
//     }
//     return max;
}

int CCardStack::Value(int exclude) const {
    int score, suitScore[4] = {0};

    for (int i = 0; i < this->Size(); i++) {
        const CCard& ci = this->at(i);
        if (i != exclude && !ci.IsJoker()) {
            suitScore[ci.Suit()] += ci.Value();
        }
    }
    score = suitScore[0];
    for (int i = 1; i < 4; i++)
        if (suitScore[i] > score)
            score = suitScore[i];

    return score;
}

int CCardStack::SuitValue(eSuit suit) const {
    int suitScore = 0;
    for (CONST_VI ci = this->begin(); ci != this->end(); ci++) {
        if (ci->Suit() == suit) {
            suitScore += ci->Value();
        }
    }
    return suitScore;
}

string CCardStack::Initials() const {
  if (Empty())
    return "<Empty>";
  else {
    std::ostringstream initials;
    CONST_VI vi=begin();
    initials << vi->Initials();
    for (vi++; vi!=end(); vi++) {
      initials << "," << vi->Initials();
    }
    return initials.str();
  }
}


// predicate for sorting
bool SortAbsolute(const CCard& l, const CCard& r) {
    return (l.GetIndex() < r.GetIndex());
}

bool SortRank(const CCard& l, const CCard& r)
{
	return l.Rank() < r.Rank();
}

bool SortSuit(const CCard& l, const CCard& r) {
    return l.Suit() < r.Suit();
}

void CCardStack::Sort()
{
	std::sort(this->begin(), this->end(), SortAbsolute);
}

void CCardStack::Sort(SortType sortType) {
    switch (sortType) {
        case ABSOLUTE_SORT: std::sort(this->begin(), this->end(), SortAbsolute);
        break;
        case RANK_SORT: std::sort(this->begin(), this->end(), SortRank);
        break;
        case SUIT_SORT: std::sort(this->begin(), this->end(), SortSuit);
        break;
        default: Sort();
    }
}

void CCardStack::Push(const CCard& card)
{
	this->push_back(card);
}

void CCardStack::Push(const CCardStack& cardstack)
{
	for(CONST_VI vi = cardstack.begin(); vi != cardstack.end(); ++vi)
		this->push_back(*vi);
}

CCard CCardStack::Pop()
{
	if(Empty())
		return 0;

	CCard card = this->back();
	this->pop_back();

	return card;
}

CCardStack CCardStack::Pop(int items)
{
	if(items > Size())
		items = Size();

	CCardStack cardstack;

	while(items > 0)
	{
		cardstack.Push(this->Pop());
		items--;
	}
	cardstack.Reverse();
	return cardstack;
}

CCard CCardStack::RemoveCard(int index)
{
	if(this->Empty())
		return 0;

	VI vi = this->begin() + index;
	CCard card = *vi;
	this->erase(vi);

	return card;
}

void CCardStack::InsertCard(int index, CCard card)
{
	VI vi = this->begin() + index;
 	this->insert(vi, card);
}

int CCardStack::GetClickedCard(int x, int y) const
{
	int i = this->Size() - 1;

	for(CONST_VI vi = this->end() - 1; vi >= this->begin(); --vi)
    {
    	if( vi->PtInCard(x, y) )
    		return i;
		i--;
	}

	return -1;
}

CCard CCardStack::GetCard(int index) const
{
	if(this->Empty())
		return 0;

	CONST_VI vi = this->begin() + index;
	CCard card = *vi;

	return card;
}

void CCardStack::SetCardsFaceUp(bool fTrue)
{
	for(VI vi = this->begin(); vi != this->end(); ++vi)
		vi->SetFaceUp(fTrue);
}

void CCardStack::AddJokers(int jokers)
{
	if(jokers < 0) jokers = 1;

	VI vi = this->end() - 1;

	this->resize(this->size() + jokers);

    for(;vi != this->end(); ++vi)
        vi->SetIdx(53);
}
